package BitCreeekClient; /**
 * @author Ivan Litsvinenka & Emanuele Ricci
 * Classe che gestisce il Thread TCP del Peer adibito a gestire le connessioni con il Tracker per aggiornare
 * la lista dei peers connessi al Tracker per un determinato torrent
 *
 */

import BitCreekLib.Host;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import java.io.EOFException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.SocketException;
import java.util.ArrayList;


public class PeerTCPThread implements Runnable {

    /**
     * Informazioni per connettersi al Tracker
     */
    private Host tracker;

    /**
     * Nome del torrent che stiamo scaricando/uploadando
     */
    private String torrentName;
    private final int TCP_SLEEP = 10000;

    /**
     * Costruttore di PeerTCPThread
     *
     * @param tracker     Le informazioni relative al Tracker
     * @param torrentName Il nome del torrent
     */
    public PeerTCPThread ( Host tracker, String torrentName ) {
        this.tracker = tracker;
        this.torrentName = torrentName;
    }


    public void run () {
        try {

            SSLSocketFactory sslsocketfactory = ( SSLSocketFactory ) SSLSocketFactory.getDefault ();
            SSLSocket sslsocket = ( SSLSocket ) sslsocketfactory.createSocket ( tracker.getAddress (), tracker.getPort () );
            

            ArrayList<Host> torrentSwarm;
            ObjectOutputStream output = new ObjectOutputStream ( sslsocket.getOutputStream () );
            ObjectInputStream input = new ObjectInputStream ( sslsocket.getInputStream () );
            while ( true ) {
                try {
                    output.writeObject ( torrentName );
                    output.flush ();
                    torrentSwarm = ( ArrayList<Host> ) input.readObject ();

                    if ( torrentSwarm.size () > 0 ) {
                        Download dl = Client.downloads.get ( this.torrentName );
                        dl.setSwarm ( torrentSwarm );
                        dl.updateSwarmAvaibility ();

                    } else {
                        // elimina il torrent fra quelli che sta scaricando visto che non ci sono piu leecher / seeder
                        Log.add ( "Elimino il torrent dalla lista (no more peers)" );
                        Client.downloads.remove ( this.torrentName );
                        return;
                    }
                } catch ( EOFException e) {                	
                	 //Log.add ( " TRACKER CHIUSO RIPROVARE LA CONNESSIONE QUANDO SI E' RIAVVIATO! RIPROVO A CONNETTERMI FRA 5 SEC" );
                	 Thread.sleep(5000);
                	 
				} catch ( SocketException e ) {
					//Log.add ( " TRACKER CHIUSO RIPROVARE LA CONNESSIONE QUANDO SI E' RIAVVIATO! RIPROVO A CONNETTERMI FRA 5 SEC" );
		            Thread.sleep(5000);
		            
		        } 
                
                catch ( Exception e ) {
                    e.printStackTrace ();
                }
                try {
                    Thread.sleep ( TCP_SLEEP );
                } catch ( InterruptedException e ) {
                    e.printStackTrace ();
                }
            }

        } catch ( SocketException e ) {
        	e.printStackTrace();
            //Log.add ( tracker.getAddress () + " TRACKER CHIUSO RIPROVARE LA CONNESSIONE QUANDO SI E' RIAVVIATO!" );
            return;
        } catch ( Exception e ) {
        	return;
        }
    }

}
